class Visitor(object):

    def visit(self, element):
        element.accept(self)

    def get_meth_name(self, element):
        return 'visit_' + type(element).__name__

    def visitByName(self, element):
        # 根据节点名获取对应处理方法
        meth_name = self.get_meth_name(element)
        # 将获取到的方法绑定到 meth
        meth = getattr(self, meth_name, None)
        # 如果没有对应方法，则将回退方法绑定到 meth
        if meth is None:
            meth = self.visit(element)
        # 返回 meth 方法调用的结果
        return meth(element)


class Element(object):

    def accept(self, v):
        return v.visit(self)


def singleton(cls, *args, **kw):
    instances = {}

    def _singleton():
        if cls not in instances:
            instances[cls] = cls(*args, **kw)
        return instances[cls]

    return _singleton


class SingletonMeta(type):
    def __init__(cls, name, bases, dict):
        super(SingletonMeta, cls).__init__(name, bases, dict)
        cls._instance = None

    def __call__(cls, *args, **kw):
        if cls._instance is None:
            cls._instance = super(SingletonMeta, cls).__call__(*args, **kw)
        else:
            print("instance already existed!")
        return cls._instance

